package com.slicktechnologies.shared.common.businessprocesslayer;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.google.gwt.core.shared.GwtIncompatible;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Index;
import com.googlecode.objectify.annotation.OnLoad;
import com.googlecode.objectify.annotation.OnSave;
import com.simplesoftwares.client.library.appstructure.search.Filter;
import com.simplesoftwares.client.library.appstructure.search.MyQuerry;
import com.simplesoftwares.client.library.helperconstants.ColumnDatatype;
import com.simplesoftwares.client.library.helperconstants.FormTypes;
import com.simplesoftwares.rebind.annatonations.SearchAnnotation;
import com.simplesoftwares.rebind.annatonations.TableAnnotation;
import com.slicktechnologies.client.config.configurations.ConfigTypes;
import com.slicktechnologies.server.GenricServiceImpl;
import com.slicktechnologies.shared.MyUtility;
import com.slicktechnologies.shared.common.helperlayer.Config;
import com.slicktechnologies.shared.common.helperlayer.ConfigCategory;
import com.slicktechnologies.shared.common.helperlayer.DocumentUpload;
import com.slicktechnologies.shared.common.helperlayer.PersonInfo;
import com.slicktechnologies.shared.common.paymentlayer.Payment;
import com.slicktechnologies.shared.common.relationalLayer.VendorRelation;

/**
 * The Class Expense. Represents the expenditure.
 */
@Entity
public class Expense extends ConcreteBusinessProcess
{
	/***********************************************Entity Attributes****************************************************/
	
	
	
	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 4405594841510984785L;

	/** The invoice number. */
	@Index 
	protected String invoiceNumber;

	/** The description. */
	protected String description;

	/** The amount. */
	protected double amount; 

	/** the vendor is not mandatory, it will be used whenever expense will be related
	 *  to any {@link Vendor} */
	@Index
	protected String vendor;// To do make vendor connected with db;

	/** The currency. */
	protected  String currency;

	/** The payments can be done in multiple times and methods */
	protected List<Payment> payments;
	
	/** Date of Expense **/
	@Index
	protected Date expenseDate;
	
	/** Payment Method for this expense **/
	protected String paymentMethod;

	/** any document related to expense **/
	protected DocumentUpload expenseDocument;

	/***********************************************Relational Attributes****************************************************/
	
	protected Key<VendorRelation> vendorKey;
	protected Key<Config>KeypaymentMethod;


	/**
	 * Instantiates a new expense.
	 */
	public Expense()
	{
		payments=new ArrayList<Payment>();
		expenseDocument=new DocumentUpload();
		invoiceNumber="";
		description="";
		vendor="";
		category="";
		currency="";
		paymentMethod="";

	}

	@SearchAnnotation(Datatype = ColumnDatatype.TEXTBOX, flexFormNumber = "13", title = "Invoice Number", variableName = "tbInvoiceNumber")
	@TableAnnotation(ColType = FormTypes.TEXTCOLUM, colNo = 9, isFieldUpdater = false, isSortable = true, title = "Invoice Number")
	public String getInvoiceNumber() {
		return invoiceNumber;
	}

	public void setInvoiceNumber(String invoiceNumber) 
	{
		if(invoiceNumber!=null)
			this.invoiceNumber = invoiceNumber.trim();
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) 
	{
		if(description!=null)
			this.description = description.trim();
	}

	@TableAnnotation(ColType = FormTypes.TEXTCOLUM, colNo = 10, isFieldUpdater = false, isSortable = true, title = "Amount")
	public Double getAmount() {
		return amount;
	}

	public void setAmount(double amount) {
		this.amount = amount;
	}

	@TableAnnotation(ColType = FormTypes.TEXTCOLUM, colNo = 8, isFieldUpdater = false, isSortable = true, title = "Vendor")
	public String getVendor() {
		return vendor;
	}

	public void setVendor(String vendor) {
		if(vendor!=null)
			this.vendor = vendor.trim();
	}

	public Key<VendorRelation> getVendorKey() {
		return vendorKey;
	}

	public void setVendorKey(Key<VendorRelation> vendorKey) {
		this.vendorKey = vendorKey;
	}
	@SearchAnnotation(Datatype = ColumnDatatype.OBJECTLISTBOXCONFIG, flexFormNumber = "12", title = "Category", variableName = "olbConfigCategory",extra="EXPENSECATEGORY")
	//@TableAnnotation(ColType = FormTypes.TEXTCOLUM, colNo = 5, isFieldUpdater = false, isSortable = true, title = "Category")
	public String getCategory() {
		return category;
	}

	public void setCategory(String category) {
		if(category!=null)
			this.category = category.trim();
	}

	public Key<ConfigCategory> getCategoryKey() {
		return categoryKey;
	}

	public void setCategoryKey(Key<ConfigCategory> categoryKey) {
		this.categoryKey = categoryKey;
	}

	public String getCurrency() {
		return currency;
	}

	public void setCurrency(String currency) {
		if(currency!=null)
			this.currency = currency.trim();
	}

	public List<Payment> getPayments() {
		return payments;
	}

	public void setPayments(List<Payment> payments) {
		this.payments = payments;
	}

	@SearchAnnotation(Datatype = ColumnDatatype.DATEBOX, flexFormNumber = "01", title = " Date", variableName = "dateBoxExpenseDate")
	@TableAnnotation(ColType = FormTypes.DATETEXTCELL, colNo = 11, isFieldUpdater = false, isSortable = true, title = "Expense Date")
	public Date getExpenseDate() {
		return expenseDate;
	}

	public void setExpenseDate(Date expenseDate) {
		this.expenseDate = expenseDate;
	}

	public String getPaymentMethod() {
		return paymentMethod;
	}

	public void setPaymentMethod(String paymentMethod) {
		if(paymentMethod!=null)
			this.paymentMethod = paymentMethod.trim();
	}

	public DocumentUpload getExpenseDocument() 
	{
		return expenseDocument;
	}

	public void setExpenseDocument(DocumentUpload expenseDocument) {
		this.expenseDocument = expenseDocument;
	}
	

	@Override
	//@SearchAnnotation(Datatype = ColumnDatatype.OBJECTLISTBOXCONFIG, flexFormNumber = "01", title = "status", variableName = "olbConfigstatus",extra="EXPENSESTATUS")
	public String getStatus() {
		// TODO Auto-generated method stub
		return super.getStatus();
	}

	@Override
	public void setStatus(String status) {
		// TODO Auto-generated method stub
		super.setStatus(status);
	}
	
	

	/**************************************************Relation Managment Part**********************************************/
	@OnSave
	@GwtIncompatible
	public void onSave()
	{
		
			GenricServiceImpl impl=new GenricServiceImpl();
			if(expenseDate!=null)
			   expenseDate= GenricServiceImpl.parseDate(expenseDate);
			categoryKey=MyUtility.getConfigCategoryFromCondition(getCategory());
			typeKey=MyUtility.getTypeKeyFromCondition(getType());
			KeypaymentMethod=MyUtility.getConfigKeyFromCondition(paymentMethod,ConfigTypes.PAYMENTMETHODS.getValue());
			
		
	}
	
	@OnLoad
	@GwtIncompatible
	public void OnLoad()
	{

		if(categoryKey!=null)
		{
			String categoryName=MyUtility.getConfigCatNameFromKey(categoryKey);
			if(categoryName.equals("")==false)
				setCategory(categoryName);
		}

		if(typeKey!=null)
		{
			String type=MyUtility.getTypeNameFromKey(typeKey);
			if(type.equals("")==false)
				setType(type);
		}

		if(vendorKey!=null)
		{
			String vendorName=MyUtility.getVendorNameFromKey(vendorKey);
			if(vendorName.equals("")==false)	
				setVendor(vendorName);
		}

		if(KeypaymentMethod!=null)
		{
			String paymentMethod=MyUtility.getConfigNameFromKey(KeypaymentMethod);
			if(paymentMethod.equals("")==false)
				setPaymentMethod(paymentMethod);
		}
	}
	
	
	public static List<String> getStatusList()
	{
		ArrayList<String> custstatuslist=new ArrayList<String>();
		custstatuslist.add(	CREATED);
		custstatuslist.add(REQUESTED);
		custstatuslist.add(REJECTED);
		custstatuslist.add(APPROVED);
		return custstatuslist;
	}

	@Override
	public void reactOnApproval() {
		
		
	}

}
